﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FlightSearchServer
{
    class CacheEntry
    {
        public object[] Outputs { set; get; }
        public FlightRoutes RetVal { set; get; }
    }

    class ResultsCache
    {
        private static ResultsCache _instance = new ResultsCache();

        private IDictionary<string, CacheEntry> results = new Dictionary<string, CacheEntry>();

        private static object locker = new object();

        private const int MAXIMUM_CACHE_SIZE = 100;

        public static ResultsCache Instance {
            get 
            {
                lock (locker)
                {
                    return _instance;
                }
            }
        }

        private ResultsCache() { }

        public void addCacheEntry(string key, CacheEntry entry)
        {
            lock (locker)
            {
                if (results.Count == MAXIMUM_CACHE_SIZE)
                {
                    // Once cache at full capacity randomly remove entry
                    Random rnd = new Random( );
                    int index = rnd.Next(MAXIMUM_CACHE_SIZE - 1);
                    results.Remove(results.Keys.ElementAt(index));
                }
                if (results.Keys.Contains(key))
                    results.Remove(key); // Refresh entry with new results
                results.Add( key, entry);
                Console.WriteLine( "Results for key {0} was added", key);
            }
        }

        public CacheEntry getCacheEntry(string key)
        {
            lock (locker)
            {
                CacheEntry result = null;
                results.TryGetValue(key, out result);
                return result;
            }
        }

        public void invalidateCacheEntry( string name, string alliance)
        {
            lock( locker) {
                var keys = (from t1 in results
                          where ( from t2 in t1.Value.RetVal where (t2.FirstLegAirCarrier == name
                                      || t2.SecondLegAirCarrier == name ) && t2.alliance == alliance
                                  select t2).ToList( ).Count > 0
                          select t1.Key).ToList( );
                foreach( string key in keys) {
                    results.Remove( key);
                }
            }
        }
    }
}
